package com.bidevalution.business.vote.launch.impl;

import com.bidevalution.business.enums.VoteAlgorithmEnum;
import com.bidevalution.business.enums.VoteOptionEnum;
import com.bidevalution.business.enums.VoteTypeEnum;
import com.bidevalution.business.exception.VoteException;
import com.bidevalution.business.service.BeSectionColumnService;
import com.bidevalution.business.service.BeSectionEnterpriseService;
import com.bidevalution.business.service.BeSectionExpertInfoService;
import com.bidevalution.business.service.BeSectionLayoutService;
import com.bidevalution.business.vote.launch.AutoVoteBaseLaunch;
import com.bidevalution.business.vote.service.BeExpertVoteService;
import com.bidevalution.business.vote.vi.AutoVoteJobVi;
import com.bidevalution.dao.entity.*;
import com.bidevalution.dao.enums.LayoutCodeEnum;
import com.bidevalution.dao.mapper.BeEvalutionOutcomeMapper;
import com.bidevalution.dao.utils.StringTools;
import com.bidevalution.service.layout.ColumnHeader;
import com.bidevalution.support.context.Constants;
import com.bidevalution.support.context.ConstantsByVoteEnum;
import com.qtp.core.util.GsonUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.*;

/**
 * 自动发起检查檢查是否同意唯一性验证表决 whc
 */
@Component
public class AutoVoteByCheckCompositeLaunch implements AutoVoteBaseLaunch {
    @Autowired
    private BeSectionColumnService beSectionColumnService;

    @Autowired
    private BeEvalutionOutcomeMapper beEvalutionOutcomeMapper;

    @Autowired
    private BeSectionEnterpriseService beSectionEnterpriseService;

    @Autowired
    private BeSectionExpertInfoService beSectionExpertInfoService;

    @Autowired
    private BeSectionLayoutService beSectionLayoutService;

    @Autowired
    private BeExpertVoteService beExpertVoteService;

    @SneakyThrows
    @Override
    public void execute(AutoVoteJobVi autoVoteJobVi) throws VoteException {
        String sectionStepId = autoVoteJobVi.getSectionStepId();
        String sectionId = autoVoteJobVi.getSectionId();
        String layoutCode = LayoutCodeEnum.Center.name();
        String expertId = autoVoteJobVi.getExpertId();

        // 先判断是否需要发起
        BeSectionColumn beSectionColumn = beSectionColumnService.getBeSectionColumn(sectionStepId, ConstantsByVoteEnum.launchPass);

        if (beSectionColumn == null) {
            return;
        }

        //1.查询 columns 配置
        BeSectionExpertInfo beSectionExpertInfo = beSectionExpertInfoService.querySectionExpertInfoById(expertId);
        BeSectionLayout beSectionLayout = beSectionLayoutService.getBeSectionLayout(sectionStepId, layoutCode);
        List<ColumnHeader> columns = beSectionColumnService.getColumnHeaderList(beSectionExpertInfo, sectionStepId, beSectionLayout, true);
        //2. 获取select和input 中英对应列关系
        Map<String, String> columnMap = new HashMap<>();
        for (ColumnHeader item : columns) {
            String columnCode = item.getCode();
            String columnText = item.getName();
            String enableEdit = item.getEnableEdit();
            String inputType = item.getColumnType();
            // 只排查 c 列
//            if (columnCode.startsWith("c") && Constants.STR_YES.equals(enableEdit)) {
                if (columnCode.startsWith("c") && ColumnHeader.ColumnType.SELECT.getCode().equals(inputType)) {
                    columnMap.put(columnCode, columnText);
                }
//            }
        }

        List<BeExpertVoteExt> beExpertVoteExts = new ArrayList<>();
        // 检查
        try {
            beExpertVoteExts = checkComposite(autoVoteJobVi, columnMap);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (beExpertVoteExts.size() > 0) {
            beExpertVoteService.createVote(beExpertVoteExts);
            throw new VoteException("最终结果不一致表决");
        }
    }

    /**
     * 查找不一致的评判结果
     * @param columnMap
     * @return
     */
    public List<BeExpertVoteExt> checkComposite(AutoVoteJobVi autoVoteJobVi, Map<String, String> columnMap)throws Exception {
        String sectionId = autoVoteJobVi.getSectionId();
        String sectionStepId = autoVoteJobVi.getSectionStepId();
        List<BeExpertVoteExt> beExpertVoteExts = new ArrayList<>();
        Set<String> cols = columnMap.keySet();
        if (cols.size() == 0) {
            return beExpertVoteExts;
        }

        // 查找当前结果
        BeEvalutionOutcome beEvalutionOutcome = new BeEvalutionOutcome();
        beEvalutionOutcome.setIsDel(Constants.STR_NO);
        beEvalutionOutcome.setSectionStepId(sectionStepId);
        beEvalutionOutcome.setLayoutCode(LayoutCodeEnum.Center.name());
        List<BeEvalutionOutcome> beEvalutionOutcomes = beEvalutionOutcomeMapper.findBeEvalutionOutcomes(beEvalutionOutcome);

        // 查询企业名称
        Map<String, String> enterpriseNameMap = beSectionEnterpriseService.findEnterpriseNameMap(sectionId, sectionStepId);

        // 检查所有字段的不一致信息
        Class clazz = BeEvalutionOutcome.class;
        for (String col : cols) {
            String colText = columnMap.get(col);
            Method method = clazz.getMethod("get"+ StringTools.firstUpperCase(StringTools.underlineToHump(col)));
            method.setAccessible(true);
            Map<String, Map<String, List<String>>> enterpriseMap = new HashMap<>();
            for (BeEvalutionOutcome item: beEvalutionOutcomes) {
                String value = (String) method.invoke(item);
                String enterpriseId = item.getEnterpriseId();
                String expertId = item.getExpertId();

                // 初始化
                Map<String, List<String>> resultMap = enterpriseMap.get(enterpriseId);
                if(resultMap == null) {
                    resultMap = new HashMap<>();
                }
                List<String> enterpriseIds = resultMap.get(value);
                if (enterpriseIds == null) {
                    enterpriseIds = new ArrayList<>();
                }
                enterpriseIds.add(expertId);

                // 赋值
                resultMap.put(value, enterpriseIds);
                enterpriseMap.put(enterpriseId, resultMap);
            }

            // 添加存在不一致的表决
            beExpertVoteExts.addAll(getBeExpertVoteExts(autoVoteJobVi, col, colText, enterpriseMap, enterpriseNameMap));
        }

        return beExpertVoteExts;
    }

    /**
     * 获取不一致的表决信息
     * @param enterpriseMap
     * @param enterpriseNameMap
     * @param colName
     * @return
     */
    @SneakyThrows
    private List<BeExpertVoteExt> getBeExpertVoteExts(AutoVoteJobVi autoVoteJobVi, String colName, String colText, Map<String, Map<String, List<String>>> enterpriseMap, Map<String, String> enterpriseNameMap) {
        String sectionId = autoVoteJobVi.getSectionId();
        String sectionStepId = autoVoteJobVi.getSectionStepId();
        List<BeExpertVoteExt> beExpertVoteExts = new ArrayList<>();

        // 循环判断是否有不一致
        for (String enterpriseId: enterpriseMap.keySet()) {
            Map<String, List<String>> resultMap = enterpriseMap.get(enterpriseId);
            String enterpriseName = enterpriseNameMap.get(enterpriseId);


            // 有不一致值
            if (resultMap.keySet().size() > 1) {
                List<BeExpertVoteDetailExt> voteDetailList = new ArrayList<>();
                for (String value: resultMap.keySet()) {
                    List<String> expertIds = resultMap.get(value);
                    for (String expertId: expertIds) {
                        BeExpertVoteDetailExt voteDetail = new BeExpertVoteDetailExt();
                        voteDetail.setExpertId(expertId);
                        voteDetail.setOwnJudge(Constants.STR_YES.equals(value) ? VoteOptionEnum.TY.getName() : VoteOptionEnum.NO_TY.getName());
                        voteDetailList.add(voteDetail);
                    }
                }


                VoteParams voteParams = new VoteParams();
                voteParams.setLayoutCode(autoVoteJobVi.getLayoutCode());
                voteParams.setSubmitCode(autoVoteJobVi.getSubmitCode());
                voteParams.setEnterpriseId(enterpriseId);
//                voteParams.setCompMethodId(compMethodId);
                voteParams.setSectionId(sectionId);
                voteParams.setSectionStepId(sectionStepId);
                voteParams.setFieldName(colName);

                BeExpertVoteExt beExpertVoteExt = new BeExpertVoteExt();
                beExpertVoteExt.setTitle(enterpriseName);
                beExpertVoteExt.setContent(colText);
                beExpertVoteExt.setSectionId(sectionId);
                beExpertVoteExt.setSectionStepId(sectionStepId);
                beExpertVoteExt.setVoteType(VoteTypeEnum.Automatic.getCode());
                beExpertVoteExt.setVoteOptions(GsonUtil.toJson(VoteOptionEnum.getNames()));
                beExpertVoteExt.setStepParams(GsonUtil.toJson(autoVoteJobVi.toCallStepJobVi()));
                beExpertVoteExt.setNextJob("updateResultCallback");
                beExpertVoteExt.setVoteParams(GsonUtil.toJson(voteParams));
                beExpertVoteExt.setVoteAlgorithm(VoteAlgorithmEnum.ShaoShuFuCongDuoShu.code);
                beExpertVoteExt.setVoteDetailList(voteDetailList);

                beExpertVoteExts.add(beExpertVoteExt);
            }
        }
        return beExpertVoteExts;
    }
}
